﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CTP.Entitys;
using CTPAPI;
using CTP.Utilty;

namespace CTP.Utilty
{
    internal class FieldConverter
    {
        #region 转换为Thost对象
        public static CThostFtdcReqUserLoginFieldWrapper ToCThostFtdcReqUserLoginFieldWrapper(TradingAccount account)
        {
            CThostFtdcReqUserLoginFieldWrapper req = new CThostFtdcReqUserLoginFieldWrapper();
            req.BrokerID = account.BranchNO;
            req.UserID = account.UserAccount;
            req.Password = account.Password;
            req.UserProductInfo = "ctp";
            req.InterfaceProductInfo = "ctp";
            return req;
        }

        public static CThostFtdcUserLogoutFieldWrapper ToCThostFtdcReqUserLogoutFieldWrapper(TradingAccount account)
        {
            CThostFtdcUserLogoutFieldWrapper req = new CThostFtdcUserLogoutFieldWrapper();
            req.BrokerID = account.BranchNO;
            req.UserID = account.UserAccount;
            return req;
        }

        public static CThostFtdcQrySettlementInfoConfirmFieldWrapper ToCThostFtdcQrySettlementInfoConfirmFieldWrapper(TradingAccount account)
        {
            CThostFtdcQrySettlementInfoConfirmFieldWrapper field = new CThostFtdcQrySettlementInfoConfirmFieldWrapper();
            field.BrokerID = account.BranchNO;
            field.InvestorID = account.UserAccount;
            return field;
        }

        public static CThostFtdcSettlementInfoConfirmFieldWrapper ToCThostFtdcSettlementInfoConfirmFieldWrapper(TradingAccount account)
        {
            CThostFtdcSettlementInfoConfirmFieldWrapper field = new CThostFtdcSettlementInfoConfirmFieldWrapper();
            field.BrokerID = account.BranchNO;
            field.InvestorID = account.UserAccount;
            return field;
        }

        public static CThostFtdcInputOrderFieldWrapper ToCThostFtdcInputOrderFieldWrapper(Order ord, TradingAccount account)
        {
            CThostFtdcInputOrderFieldWrapper field = new CThostFtdcInputOrderFieldWrapper();
            field.BrokerID = account.BranchNO;
            field.InvestorID = account.UserAccount;
            field.InstrumentID = ord.Code;
            field.OrderPriceType = (sbyte)ToOrderPriceType(ord.PriceMode);
            field.Direction = (sbyte)ToTFtdcDirectionType(ord.Side);
            field.CombOffsetFlag = string.Format("{0}", (char)ToTThostFtdcOffsetFlagType(ord.OpenClose));
            field.CombHedgeFlag = string.Format("{0}", (char)ToTThostFtdcHedgeFlagType(ord.HedgeFlag));
            field.LimitPrice = ord.PriceMode == PriceMode.MarketPrice ? 0 : double.Parse(ord.Price.ToString("F2"));
            field.VolumeTotalOriginal = (int)ord.Amount;
            field.TimeCondition = (sbyte)ToTThostFtdcTimeConditionType(ord.PriceMode);
            field.VolumeCondition = (sbyte)TThostFtdcVolumeConditionType.THOST_FTDC_VC_AV;
            field.MinVolume = 1;
            field.ContingentCondition = (sbyte)TThostFtdcContingentConditionType.THOST_FTDC_CC_Immediately;
            field.ForceCloseReason = (sbyte)TFtdcForceCloseReasonType.THOST_FTDC_FCC_NotForceClose;
            field.IsAutoSuspend = 1;//自动挂起标志: 是
            field.UserForceClose = 0;//用户强平标志: 否
            field.OrderRef = ord.OrderRef;

            return field;
        }

        public static CThostFtdcQryOrderFieldWrapper ToCThostFtdcQryOrderFieldWrapper(Order ord, TradingAccount account)
        {
            CThostFtdcQryOrderFieldWrapper field = new CThostFtdcQryOrderFieldWrapper();
            field.BrokerID = account.BranchNO;
            field.InvestorID = account.UserAccount;
            field.InstrumentID = ord.Code;
            field.OrderSysID = ord.OrderID.PadLeft(12);

            return field;
        }

        public static CThostFtdcInputOrderActionFieldWrapper ToCThostFtdcInputOrderActionFieldWrapper(Order ord, TradingAccount account)
        {
            CThostFtdcInputOrderActionFieldWrapper field = new CThostFtdcInputOrderActionFieldWrapper();
            field.BrokerID = account.BranchNO;
            field.InvestorID = account.UserAccount;
            field.OrderSysID = ord.OrderID.PadLeft(12);
            field.ActionFlag = (sbyte)TFtdcActionFlag.THOST_FTDC_AF_Delete;

            return field;
        }

        public static CThostFtdcQryTradingAccountFieldWrapper ToCThostFtdcQryTradingAccountFieldWrapper(TradingAccount account)
        {
            CThostFtdcQryTradingAccountFieldWrapper field = new CThostFtdcQryTradingAccountFieldWrapper();
            field.BrokerID = account.BranchNO;
            field.InvestorID = account.UserAccount;
            return field;
        }

        public static CThostFtdcQryInvestorPositionFieldWrapper ToCThostFtdcQryInvestorPositionFieldWrapper(TradingAccount account)
        {
            CThostFtdcQryInvestorPositionFieldWrapper field = new CThostFtdcQryInvestorPositionFieldWrapper();
            field.BrokerID = account.BranchNO;
            field.InvestorID = account.UserAccount;
            return field;
        }
        #endregion

        #region To
        public static TFtdcDirectionType ToTFtdcDirectionType(Side side)
        {
            switch (side)
            {
                case Side.Buy:
                    return TFtdcDirectionType.THOST_FTDC_D_Buy;
                case Side.Sell:
                    return TFtdcDirectionType.THOST_FTDC_D_Sell;
                default:
                    return TFtdcDirectionType.THOST_FTDC_D_Buy;
            }
        }
        public static TThostFtdcOrderPriceType ToOrderPriceType(PriceMode mode)
        {
            switch (mode)
            {
                case PriceMode.LimitPrice:
                    return TThostFtdcOrderPriceType.THOST_FTDC_OPT_LimitPrice;
                case PriceMode.MarketPrice:
                    return TThostFtdcOrderPriceType.THOST_FTDC_OPT_AnyPrice;
                default:
                    return TThostFtdcOrderPriceType.THOST_FTDC_OPT_LimitPrice;
            }
        }

        public static TThostFtdcOffsetFlagType ToTThostFtdcOffsetFlagType(OpenClose offset)
        {
            switch (offset)
            {
                case OpenClose.Open: return TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open;
                case OpenClose.Close: return TThostFtdcOffsetFlagType.THOST_FTDC_OF_Close;
                case OpenClose.CloseToday: return TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday;
                case OpenClose.CloseYestoday: return TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseYesterday;
                case OpenClose.ForceClose: return TThostFtdcOffsetFlagType.THOST_FTDC_OF_ForceClose;
                default:
                    return TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open;
            }
        }

        public static TThostFtdcHedgeFlagType ToTThostFtdcHedgeFlagType(HedgeFlag hedgeFlag)
        {
            switch (hedgeFlag)
            {
                case HedgeFlag.Speculation: return TThostFtdcHedgeFlagType.THOST_FTDC_HF_Speculation;
                case HedgeFlag.Hedge: return TThostFtdcHedgeFlagType.THOST_FTDC_HF_Hedge;
                default:
                    return TThostFtdcHedgeFlagType.THOST_FTDC_HF_Hedge;
            }
        }

        public static TThostFtdcTimeConditionType ToTThostFtdcTimeConditionType(PriceMode mode)
        {
            switch (mode)
            {
                case PriceMode.MarketPrice:
                    return TThostFtdcTimeConditionType.THOST_FTDC_TC_IOC;
                default:
                    return TThostFtdcTimeConditionType.THOST_FTDC_TC_GFD;
            }
        }

        #endregion

        #region From

        public static OrderState FromTThostFtdcOrderStatus(TThostFtdcOrderStatus status)
        {
            switch (status)
            {
                case TThostFtdcOrderStatus.THOST_FTDC_OST_AllTraded:
                    return OrderState.Filled;
                case TThostFtdcOrderStatus.THOST_FTDC_OST_Canceled:
                    return OrderState.Canceled;
                case TThostFtdcOrderStatus.THOST_FTDC_OST_NoTradeNotQueueing://未成交不在队列,状态待确认
                    return OrderState.ToBeConfirmed;
                case TThostFtdcOrderStatus.THOST_FTDC_OST_NoTradeQueueing:
                    return OrderState.Reported;
                case TThostFtdcOrderStatus.THOST_FTDC_OST_NotTouched:
                    return OrderState.UnAck;
                case TThostFtdcOrderStatus.THOST_FTDC_OST_PartTradedNotQueueing:
                    return OrderState.PartFilledAndCancelled;
                case TThostFtdcOrderStatus.THOST_FTDC_OST_PartTradedQueueing:
                    return OrderState.PartFilled;
                case TThostFtdcOrderStatus.THOST_FTDC_OST_Unknown:
                    return OrderState.Unknow;
                default:
                    return OrderState.ToBeConfirmed;
            }
        }

        public static OrderState FromTThostFtdcOrderSubmitStatus(TThostFtdcOrderSubmitStatus status)
        {
            switch (status)
            {
                case TThostFtdcOrderSubmitStatus.THOST_FTDC_OSS_Accepted:
                    return OrderState.Reported;
                case TThostFtdcOrderSubmitStatus.THOST_FTDC_OSS_CancelRejected:
                    return OrderState.ToBeConfirmed;
                case TThostFtdcOrderSubmitStatus.THOST_FTDC_OSS_CancelSubmitted:
                    return OrderState.ReportedCancel;
                case TThostFtdcOrderSubmitStatus.THOST_FTDC_OSS_InsertRejected:
                    return OrderState.PlaceRejected;
                case TThostFtdcOrderSubmitStatus.THOST_FTDC_OSS_InsertSubmitted:
                    return OrderState.Reported;
                case TThostFtdcOrderSubmitStatus.THOST_FTDC_OSS_ModifyRejected:
                    return OrderState.ToBeConfirmed;
                case TThostFtdcOrderSubmitStatus.THOST_FTDC_OSS_ModifySubmitted:
                    return OrderState.Reported;
                default:
                    return OrderState.ToBeConfirmed;
            }
        }

        public static OpenClose FromTThostFtdcOffsetFlagType(TThostFtdcOffsetFlagType offset)
        {
            switch (offset)
            {
                case TThostFtdcOffsetFlagType.THOST_FTDC_OF_Close:
                    return OpenClose.Close;
                case TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseToday:
                    return OpenClose.CloseToday;
                case TThostFtdcOffsetFlagType.THOST_FTDC_OF_CloseYesterday:
                    return OpenClose.CloseYestoday;
                case TThostFtdcOffsetFlagType.THOST_FTDC_OF_ForceClose:
                    return OpenClose.ForceClose;
                case TThostFtdcOffsetFlagType.THOST_FTDC_OF_Open:
                    return OpenClose.Open;
                default:
                    throw new NotImplementedException("不会有这种情况");
            }
        }

        public static Side FromTFtdcDirectionType(TFtdcDirectionType direction)
        {
            switch (direction)
            {
                case TFtdcDirectionType.THOST_FTDC_D_Buy:
                    return Side.Buy;
                case TFtdcDirectionType.THOST_FTDC_D_Sell:
                    return Side.Sell;
                default:
                    throw new NotImplementedException("Not need to do");
            }
        }

        public static PosSide FromTThostFtdcPosiDirection(TThostFtdcPosiDirection direction)
        {
            switch (direction)
            {
                case TThostFtdcPosiDirection.THOST_FTDC_PD_Long:
                    return PosSide.More;
                case TThostFtdcPosiDirection.THOST_FTDC_PD_Short:
                    return PosSide.Short;
                case TThostFtdcPosiDirection.THOST_FTDC_PD_Net:
                    return PosSide.Clear;
                default:
                    throw new NotImplementedException("不会有这种情况");
            }
        }

        public static PriceMode FromOrderPriceType(TThostFtdcOrderPriceType mode)
        {
            switch (mode)
            {
                case TThostFtdcOrderPriceType.THOST_FTDC_OPT_AnyPrice: return PriceMode.MarketPrice;
                case TThostFtdcOrderPriceType.THOST_FTDC_OPT_LimitPrice: return PriceMode.LimitPrice;
                case TThostFtdcOrderPriceType.THOST_FTDC_OPT_LastPrice: return PriceMode.LastPrice;
                default:
                    throw new NotImplementedException();
            }
        }
        #endregion
    }
}
